package cloudspace.vm.javassist;

import java.util.List;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.expr.Expr;
import cloudspace.vm.VM;
import cloudspace.vm.javassist.AbstractCommand.SignatureType;

/**
 * This command adds a method to a Class. It is defined by the following
 * configuration line.
 * 
 * translate AddMethod <Class Name> <Return Type> <Method Name> <Parameter type>
 * <Method Body>
 * 
 * The class name is the fully defined name of the class to add the method to.
 * It can be a super class. The return type is the return type for the method.
 * The method name is the simple name designating the method. The parameter type
 * is the parameter type for the first parameter, the current implementation
 * only supports one parameter methods. The method body is the body of the
 * method to be added, it supports the use of macros.
 * 
 * @author Mike Woods
 * 
 */
public class AddMethod implements CommandInterface
{
	List<String> configArgs;

	public AddMethod(List<String> args)
	{
		configArgs = args;
	}

	@Override
	public String getReplacement()
	{
		// TODO Auto-generated method stub
		return configArgs.get(5).substring(1, configArgs.get(5).length() - 1);
	}

	@Override
	public String getSignature()
	{
		return configArgs.get(1);
	}

	@Override
	public SignatureType getSignatureType()
	{
		return SignatureType.STATICDEFINITION;
	}

	@Override
	public void translate(Expr call, boolean isSuper)
			throws MalformedCommandException, CannotCompileException
	{
		throw new MalformedCommandException("This command is not implemented");

	}

	@Override
	public void translate(CtMethod member, String expressionName)
			throws MalformedCommandException, CannotCompileException,
			MalformedCommandException
	{
		throw new MalformedCommandException("This command is not implemented");
		// member.addLocalVariable(name, type);

	}

	@Override
	public void translate(CtClass clazz) throws MalformedCommandException,
			CannotCompileException
	{

		try
		{
			CtClass superClazz = clazz.getSuperclass();
			while (superClazz != null)
			{
				if (superClazz.getName().equals(getSignature()))
				{
					// CtClass returnClazz =
					// VM.identifyCurrentVM().getClassPool().get(configArgs.get(2));
					CtClass param = VM.currentVM().getClassPool().get(
							configArgs.get(4));
					CtMethod methodToAdd = new CtMethod(CtClass.voidType,
							configArgs.get(3), new CtClass[] { param }, clazz);
					String replacement = getReplacement();
					methodToAdd.setBody(replacement);
					clazz.addMethod(methodToAdd);
				}
				superClazz = superClazz.getSuperclass();
			}
		}
		catch (NotFoundException e)
		{
			;
		}

	}

}
